package org.mozhu.mboot.core.json.jackson.jdk.deser;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JavaType;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class DateDeserializer extends org.mozhu.mboot.core.json.jackson.jdk.deser.JdkDeserializerBase<Date> {

    private static final long serialVersionUID = 6703133995726075845L;

    private SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    private SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZ");
    private SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
    private List<SimpleDateFormat> sdfs = new ArrayList<SimpleDateFormat>();

    public DateDeserializer() {
        super(Date.class);
        sdfs.add(sdf1);
        sdfs.add(sdf2);
        sdfs.add(sdf3);
        sdfs.add(sdf4);
    }

    @Override
    public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
        switch (jp.getCurrentToken()) {
            // TODO support "time":longvalue
            case VALUE_NUMBER_INT:
                return new Date(jp.getLongValue());
            case VALUE_STRING:
                String str = jp.getText().trim();
                if (str.length() == 0) {
                    return null;
                }
                return parseDate(jp, str);
            default:
                break;
        }
        throw ctxt.wrongTokenException(jp, (JavaType) null, JsonToken.START_ARRAY, "expected JSON Array, Number or String");
    }


    private Date parseDate(JsonParser jp, String str) throws JsonProcessingException {
        for (SimpleDateFormat sdf : sdfs) {
            try {
                return sdf.parse(str);
            } catch (Exception e) {
            }
        }
        throw new JsonParseException(jp, "can't parse source[" + str + "] to java.util.Date");
    }

}
